home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
advancec.arc
/
MENU.C
< prev
next >
Wrap
Text File
|
1992-01-24
|
6KB
|
256 lines
/*
menu.c
menu manager routines and variables
*/
#include "usrif.h"
#undef NULL
#include "stdio.h"
/* global variables */
extern rect_t screen;
extern vport_t *the_port;
extern point_t cursor;
/* menu border in pixels */
#define BDR 3
/* menu text height in pixels */
#define TH 12
int pop_up_menu( num_items, items)
int num_items;
char *items[];
{
char *look, *animate_seg();
text_t *t[MAX_MENUS];
rect_t area, bmap;
rect_t *bbox, *text_bbox();
int i, h, w, mw = 0, x, y;
seg_t *menu;
key_t *key;
void save_bitmap(), restore_bitmap();
/* determine maximum item width */
for(i = 0; i < num_items; i++)
{
bbox = text_bbox(items[i], LEFT, BOTTOM);
w = bbox->right - bbox->left;
free(bbox);
if(w > mw)
mw = w;
}
/* determine size of menu */
h = (TH + 2 * BDR) * num_items + 2;
w = mw + 2 * BDR;
/* determine location of menu */
x = cursor.x; y = cursor.y;
/* greater than left edge of screen? */
if(x > (w / 2 + BDR))
x -= w / 2;
else
x = w / 2 + BDR;
/* less than right edge of screen? */
if( (x + w) > screen.right)
x -= w + BDR;
else
x = screen.right - w - BDR;
/* greater than bottom edge of screen? */
if(y > (h / 2 + BDR))
y -= h / 2;
else
y = h / 2 + BDR;
/* less than top edge of screen? */
if( (y + h) > screen.top)
y -= h + BDR;
else
y = screen.top - h - BDR;
set_rect(&area, x, y, x + w, y + h);
set_rect(&bmap, x - 1, y - 1, x + w + 1, y + h + 1);
cr_seg("menu");
add_attr(RESET);
add_attr(FILL);
add_rect(copy_rect(&area));
add_attr(NOFILL);
add_attr(BLACK);
add_rect(copy_rect(&area));
for(i = 0; i < num_items; i++)
{
t[i] = inst_text(items[i],
x + 2 + w / 2, y + 2 * BDR + i * (TH + 2 * BDR),
MIDDLE, BOTTOM);
/*
If you want menu items left-justified,
use this text command:
t[i] = inst_text(items[i],
x + 2 * BDR, y + 2 * BDR + i * (TH + 2 * BDR),
LEFT, BOTTOM);
*/
add_text(t[i]);
}
menu = cl_seg();
/* save bit-map region where menu goes */
save_bitmap(&bmap);
/* draw menu in bit map */
hide_cursor();
draw_seg(menu, the_port);
/* re-adjust text bboxs to world space */
for(i = 0; i < num_items; i++)
{
set_rect(t[i]->bbox,
x + 1, y + i * (TH + 2 * BDR) + 1,
x - 3 + w, y + (i + 1) * (TH + 2 * BDR)) - 2;
}
/* animate menu item selection */
show_cursor();
look = animate_seg(menu);
del_seg(menu);
/* replace bit-map region */
restore_bitmap(&bmap);
/* return selected item */
for(i = 0;i<num_items;i++)
if(strcmp(look, items[i]) == 0)
return(i);
return(-1);
}
text_t *active = NULL;
char *animate_seg(seg)
seg_t *seg;
{
char *item;
event_t *myevent;
key_t *test;
text_t *t;
for(;;)
{
myevent = get_next_event();
if(myevent->what == UP_BUTTON_EVENT)
{
if(active == NULL)
return(NULL);
else
{
item = active->text;
active = NULL;
return(item);
}
}
else if( pt_in_rect( seg->bbox, &(myevent->where) ))
{
test = seg->data;
while(test != NULL)
{
/* is text primitive */
if(test->type == TEXT)
{
t = test->key.text;
if(pt_in_rect(t->bbox, &(myevent->where)))
{
if(active == NULL)
{
/* make t the active text */
xor_rect(t->bbox, FILL);
active = t;
}
else if(active != t)
{
/* dim old text, make t active */
xor_rect(active->bbox, FILL);
xor_rect(t->bbox, FILL);
active = t;
}
/* else do nothing */
}
}
test = test->next;
}
}
/* must be outside menu area */
else if(active != NULL)
{
xor_rect(active->bbox, FILL);
active = NULL;
}
}
}
void save_bitmap( rect )
rect_t *rect;
{
hide_cursor();
/*
save rectangular area of bit map
*/
show_cursor();
}
void restore_bitmap( rect )
rect_t *rect;
{
hide_cursor();
/*
restore rectangular area of bit map
*/
show_cursor();
}
/*
Instead of using the segmentation system's
XOR feature, which clips and maps primitives,
use this function to provide the fastest
possible animation speed.
*/
xor_rect( rect, how)
rect_t *rect;
int how;
{
switch( how )
{
case FILL :
/*
Xor FILLed rectangle
*/
break;
case FRAME :
/*
Xor FRAMEd rectangle
*/
break;
}
}